#include "gameState.h"

// Functions computing if a piece (king or other) is under check.
// And also getAttackInfo computes information about every attack on board.

void GameState::computeIsUnderCheck()
{
    isPlayerUnderCheck = false;
    isEnemyUnderCheck = false;
    
    int wk_row, wk_col, bk_row, bk_col;     
    
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            if(board[i][j] == WHITE_KING )
            {
            	wk_row = i;
            	wk_col = j;
            }
            if(board[i][j] == BLACK_KING)
            {
					bk_row = i;            
            	bk_col = j;
            }
      	}   
    }  
 
	 if(round == WHITE && isFieldUnderCheck(wk_row, wk_col, BLACK))
	 	isPlayerUnderCheck = true;
	 if(round == WHITE && isFieldUnderCheck(bk_row, bk_col, WHITE))
	 	isEnemyUnderCheck = true;
	 	
	 if(round == BLACK && isFieldUnderCheck(bk_row, bk_col, WHITE))
	 	isPlayerUnderCheck = true;
	 if(round == BLACK && isFieldUnderCheck(wk_row, wk_col, BLACK))
	 	isEnemyUnderCheck = true;
        
}

bool GameState::computeIsLosingState() const
{
	if(!isPlayerUnderCheck)
	{
		return false;
   }
	
	std::vector<Move> moves = generateAllMoves();
	 
	if(moves.size() == 0)
	{
		return true;
	}

	return false;
}

bool GameState::isFieldUnderCheck(int row, int col, Colour byWhom)
{
	 bool underCheck = false;
    
    int knight_directions[8][2] = { {-2,-1}, {-2,1}, {2,-1}, {2,1}, {-1,-2}, {1,-2}, {-1,2}, {1,2} };
    int bishop_directions[4][2] = { {-1,-1}, {-1,1}, {1,-1}, {1,1}  };
    int rook_directions[4][2] = { {-1,0}, {1,0}, {0,-1}, {0,1}  };
	 int white_pawn_directions[2][2] = { {1,-1}, {1,1} };
	 int black_pawn_directions[2][2] = { {-1,-1}, {-1,1} };
	 
	 int trow, tcol;		 
	 
	 // Knight beatings
	 for(int i = 0; i < 8; i++)
	 {
	 	trow = row + knight_directions[i][0];
	 	tcol = col + knight_directions[i][1];
	 	
	 	if(inBoard(tcol, trow) && byWhom == BLACK && board[trow][tcol] == BLACK_KNIGHT)
	 		underCheck = true;
	
	 	if(inBoard(tcol, trow) && byWhom == WHITE && board[trow][tcol] == WHITE_KNIGHT)
	 		underCheck = true;
	 }	 
	 
	 // Bishop beatings
	 for(int i = 0; i < 4; i++)
	 {
	 	trow = row + bishop_directions[i][0];
	 	tcol = col + bishop_directions[i][1];
	 
	 	while(inBoard(trow, tcol) && board[trow][tcol] == EMPTY)
	 	{
	 		trow += bishop_directions[i][0];
	 		tcol += bishop_directions[i][1];
	 	}
	 	
	 	if(inBoard(trow, tcol) && byWhom == BLACK && (board[trow][tcol] == BLACK_QUEEN || board[trow][tcol] == BLACK_BISHOP))
	 		underCheck = true;
	 		 	
	 	if(inBoard(trow, tcol) && byWhom == WHITE && (board[trow][tcol] == WHITE_QUEEN || board[trow][tcol] == WHITE_BISHOP))
	 		underCheck = true;	
    }	
    
    // Rook beatings
    for(int i = 0; i < 4; i++)
    {
    	trow = row + rook_directions[i][0];
	 	tcol = col + rook_directions[i][1];
	 
	 	while(inBoard(trow, tcol) && board[trow][tcol] == EMPTY)
	 	{
	 		trow += rook_directions[i][0];
	 		tcol += rook_directions[i][1];
	 	}
	 	
	 	if(inBoard(trow, tcol) && byWhom == BLACK && (board[trow][tcol] == BLACK_QUEEN || board[trow][tcol] == BLACK_ROOK))
	 		underCheck = true;
	
	 	if(inBoard(trow, tcol) && byWhom == WHITE && (board[trow][tcol] == WHITE_QUEEN || board[trow][tcol] == WHITE_ROOK))
	 		underCheck = true;
	 }
	 
	 // Pawn beatings	     
    for(int i = 0; i < 2; i++)
    {
    	if(byWhom == BLACK)
    	{
    		trow = row + black_pawn_directions[i][0];
	 		tcol = col + black_pawn_directions[i][1];
	 	
	 		if(inBoard(trow, tcol) && board[trow][tcol] == BLACK_PAWN)
	 			underCheck = true;
		}
    
    	if(byWhom == WHITE)
		{
    		trow = row + white_pawn_directions[i][0];
	 		tcol = col + white_pawn_directions[i][1];
	 	
	 		if(inBoard(trow, tcol) && board[trow][tcol] == WHITE_PAWN)
	 			underCheck = true;
	 	}
	 }
	return underCheck;
}

void GameState::getAttackInfo()
{
    std::vector<Move> currentPlayerMoves = generateAllSimpleMoves(round, true);
    std::vector<Move> enemyPlayerMoves = generateAllSimpleMoves(Util::opposite(round), true);
    
    for(int i = 0; i < 2; i++)
        for(int j = 0; j < 8; j++)
            for(int k = 0; k < 8; k++)
                attackInfo[i][j][k] = 0;

    int r, c;
                
    for(int i = 0; i < currentPlayerMoves.size(); i++)
    {
        r = currentPlayerMoves[i].destination_row;
        c = currentPlayerMoves[i].destination_col;
        
        // A straight pawn move isn't beating
        if( board[currentPlayerMoves[i].source_row][currentPlayerMoves[i].source_col] == ((round == WHITE) ? WHITE_PAWN : BLACK_PAWN) &&
            c == (int)currentPlayerMoves[i].source_col)
            ;
        else
            attackInfo[0][r][c]++;
    }

          
    for(int i = 0; i < enemyPlayerMoves.size(); i++)
    {
        r = enemyPlayerMoves[i].destination_row;
        c = enemyPlayerMoves[i].destination_col;
        
        // A straight pawn move isn't beating
        if( board[enemyPlayerMoves[i].source_row][enemyPlayerMoves[i].source_col] == ((round == WHITE) ? BLACK_PAWN : WHITE_PAWN) &&
            c == (int)enemyPlayerMoves[i].source_col)
            ;
        else
            attackInfo[1][r][c]++; 
    }
}
